using System;
using System.Collections.Generic;
using System.Text;
namespace MicroMsg.Common.Algorithm
{
	public class BigInteger
	{
		private const long IMASK = 4294967295L;
		private const int BITS_PER_BYTE = 8;
		private const int BYTES_PER_INT = 4;
		private int sign;
		private int[] magnitude;
		private int nBits = -1;
		private int nBitLength = -1;
		private long mQuote = -1L;
		private static byte[] rndMask;
		private static readonly byte[] bitCounts;
		private static readonly byte[] bitLengths;
		public static readonly BigInteger ZERO;
		public static readonly BigInteger ONE;
		private static readonly BigInteger TWO;
		private long MQuote
		{
			get
			{
				if (this.mQuote != -1L)
				{
					return this.mQuote;
				}
				if ((this.magnitude[this.magnitude.Length - 1] & 1) == 0)
				{
					return -1L;
				}
				long long_ = (long)((~this.magnitude[this.magnitude.Length - 1] | 1) & -1);
				this.mQuote = this._modInverse(long_, 4294967296L);
				return this.mQuote;
			}
		}
		public virtual int LowestSetBit
		{
			get
			{
				if (this.Equals(BigInteger.ZERO))
				{
					return -1;
				}
				int num = this.magnitude.Length - 1;
				while (num >= 0 && this.magnitude[num] == 0)
				{
					num--;
				}
				int num2 = 31;
				while (num2 > 0 && (long)((long)this.magnitude[num] << num2) != (long)((ulong)-2147483648))
				{
					num2--;
				}
				return (this.magnitude.Length - 1 - num) * 32 + (31 - num2);
			}
		}
		private BigInteger()
		{
		}
		private BigInteger(int nWords)
		{
			this.sign = 1;
			this.magnitude = new int[nWords];
		}
		private BigInteger(int signum, int[] int_0)
		{
			this.sign = signum;
			if (int_0.Length > 0)
			{
				int num = 0;
				while (num < int_0.Length && int_0[num] == 0)
				{
					num++;
				}
				if (num == 0)
				{
					this.magnitude = int_0;
					return;
				}
				int[] array = new int[int_0.Length - num];
				Array.Copy(int_0, num, array, 0, array.Length);
				this.magnitude = array;
				if (array.Length == 0)
				{
					this.sign = 0;
					return;
				}
			}
			else
			{
				this.magnitude = int_0;
				this.sign = 0;
			}
		}
		public BigInteger(string sval) : this(sval, 10)
		{
		}
		public BigInteger(string sval, int int_0)
		{
			if (sval.get_Length() == 0)
			{
				throw new FormatException("Zero length BigInteger");
			}
			if (int_0 < 2 || int_0 > 36)
			{
				throw new FormatException("Radix out of range");
			}
			int i = 0;
			this.sign = 1;
			if (sval.get_Chars(0) == '-')
			{
				if (sval.get_Length() == 1)
				{
					throw new FormatException("Zero length BigInteger");
				}
				this.sign = -1;
				i = 1;
			}
			while (i < sval.get_Length())
			{
				if (char.GetNumericValue(sval.get_Chars(i)) != 0.0)
				{
					break;
				}
				i++;
			}
			if (i >= sval.get_Length())
			{
				this.sign = 0;
				this.magnitude = new int[0];
				return;
			}
			BigInteger bigInteger = BigInteger.ZERO;
			BigInteger bigInteger_ = BigInteger.valueOf((long)int_0);
			while (i < sval.get_Length())
			{
				bigInteger = bigInteger.multiply(bigInteger_).vmethod_1(BigInteger.valueOf((long)char.GetNumericValue(sval.get_Chars(i))));
				i++;
			}
			this.magnitude = bigInteger.magnitude;
		}
		public BigInteger(byte[] bval)
		{
			if (bval.Length == 0)
			{
				throw new FormatException("Zero length BigInteger");
			}
			this.sign = 1;
			if (bval[0] < 0)
			{
				this.sign = -1;
			}
			this.magnitude = this.makeMagnitude(bval, this.sign);
			if (this.magnitude.Length == 0)
			{
				this.sign = 0;
			}
		}
		private int[] makeMagnitude(byte[] bval, int sign)
		{
			if (sign < 0)
			{
				int i;
				for (i = 0; i < bval.Length - 1; i++)
				{
					if (bval[i] != 255)
					{
						break;
					}
				}
				int num = bval.Length;
				bool flag = false;
				if (bval[i] == 128)
				{
					int j = i + 1;
					while (j < bval.Length && bval[j] == 0)
					{
						j++;
					}
					if (j == bval.Length)
					{
						num++;
						flag = true;
					}
				}
				int num2 = (num - i + 3) / 4;
				int num3 = (num - i) % 4;
				if (num3 == 0)
				{
					num3 = 4;
				}
				int[] array = new int[num2];
				int num4 = 0;
				int num5 = 0;
				if (flag)
				{
					num3--;
					if (num3 <= 0)
					{
						num5++;
						num3 = 4;
					}
				}
				for (int j = i; j < bval.Length; j++)
				{
					num4 <<= 8;
					num4 |= (int)(~bval[j] & 255);
					num3--;
					if (num3 <= 0)
					{
						array[num5] = num4;
						num5++;
						num3 = 4;
						num4 = 0;
					}
				}
				return this.method_1(array);
			}
			int num6 = 0;
			while (num6 < bval.Length && bval[num6] == 0)
			{
				num6++;
			}
			if (num6 >= bval.Length)
			{
				return new int[0];
			}
			int num7 = (bval.Length - num6 + 3) / 4;
			int num8 = (bval.Length - num6) % 4;
			if (num8 == 0)
			{
				num8 = 4;
			}
			int[] array2 = new int[num7];
			int num9 = 0;
			int num10 = 0;
			for (int k = num6; k < bval.Length; k++)
			{
				num9 <<= 8;
				num9 |= (int)(bval[k] & 255);
				num8--;
				if (num8 <= 0)
				{
					array2[num10] = num9;
					num10++;
					num8 = 4;
					num9 = 0;
				}
			}
			return array2;
		}
		public BigInteger(int sign, byte[] byte_0)
		{
			if (sign < -1 || sign > 1)
			{
				throw new FormatException("Invalid sign value");
			}
			if (sign == 0)
			{
				this.sign = 0;
				this.magnitude = new int[0];
				return;
			}
			this.magnitude = this.makeMagnitude(byte_0, 1);
			this.sign = sign;
		}
		public BigInteger(int numBits, Random random_0)
		{
			if (numBits < 0)
			{
				throw new ArgumentException("numBits must be non-negative");
			}
			int num = (numBits + 7) / 8;
			byte[] array = new byte[num];
			if (num > 0)
			{
				this.nextRndBytes(random_0, array);
				byte[] expr_4B_cp_0 = array;
				int expr_4B_cp_1 = 0;
				expr_4B_cp_0[expr_4B_cp_1] &= BigInteger.rndMask[8 * num - numBits];
			}
			this.magnitude = this.makeMagnitude(array, 1);
			this.sign = 1;
			this.nBits = -1;
			this.nBitLength = -1;
		}
		private void nextRndBytes(Random random_0, byte[] bytes)
		{
			int num = bytes.Length;
			int num2 = 0;
			int num3 = 0;
			while (true)
			{
				for (int i = 0; i < 4; i++)
				{
					if (num2 == num)
					{
						return;
					}
					num3 = ((i == 0) ? random_0.Next() : (num3 >> 8));
					bytes[num2++] = (byte)num3;
				}
			}
		}
		public BigInteger(int bitLength, int certainty, Random random_0)
		{
			int num = (bitLength + 7) / 8;
			byte[] array = new byte[num];
			do
			{
				if (num > 0)
				{
					this.nextRndBytes(random_0, array);
					byte[] expr_A6_cp_0 = array;
					int expr_A6_cp_1 = 0;
					expr_A6_cp_0[expr_A6_cp_1] &= BigInteger.rndMask[8 * num - bitLength];
				}
				this.magnitude = this.makeMagnitude(array, 1);
				this.sign = 1;
				this.nBits = -1;
				this.nBitLength = -1;
				this.mQuote = -1L;
				if (certainty > 0 && bitLength > 2)
				{
					this.magnitude[this.magnitude.Length - 1] |= 1;
				}
			}
			while (this.getBitLength() != bitLength || !this.isProbablePrime(certainty));
		}
		public virtual BigInteger vmethod_0()
		{
			if (this.sign < 0)
			{
				return this.negate();
			}
			return this;
		}
		private int[] method_0(int[] int_0, int[] int_1)
		{
			int i = int_0.Length - 1;
			int j = int_1.Length - 1;
			long num = 0L;
			while (j >= 0)
			{
				num += ((long)int_0[i] & (long)((ulong)-1)) + ((long)int_1[j--] & (long)((ulong)-1));
				int_0[i--] = (int)num;
				num = SupportClass.URShift(num, 32);
			}
			while (i >= 0)
			{
				if (num == 0L)
				{
					break;
				}
				num += ((long)int_0[i] & (long)((ulong)-1));
				int_0[i--] = (int)num;
				num = SupportClass.URShift(num, 32);
			}
			return int_0;
		}
		private int[] method_1(int[] int_0)
		{
			int i = int_0.Length - 1;
			long num = ((long)int_0[i] & (long)((ulong)-1)) + 1L;
			int_0[i--] = (int)num;
			num = SupportClass.URShift(num, 32);
			while (i >= 0)
			{
				if (num == 0L)
				{
					break;
				}
				num += ((long)int_0[i] & (long)((ulong)-1));
				int_0[i--] = (int)num;
				num = SupportClass.URShift(num, 32);
			}
			return int_0;
		}
		public virtual BigInteger vmethod_1(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign == 0 || bigInteger_0.magnitude.Length == 0)
			{
				return this;
			}
			if (this.sign != 0 && this.magnitude.Length != 0)
			{
				if (bigInteger_0.sign < 0)
				{
					if (this.sign > 0)
					{
						return this.subtract(bigInteger_0.negate());
					}
				}
				else
				{
					if (this.sign < 0)
					{
						return bigInteger_0.subtract(this.negate());
					}
				}
				int[] array;
				int[] int_;
				if (this.magnitude.Length < bigInteger_0.magnitude.Length)
				{
					array = new int[bigInteger_0.magnitude.Length + 1];
					Array.Copy(bigInteger_0.magnitude, 0, array, 1, bigInteger_0.magnitude.Length);
					int_ = this.magnitude;
				}
				else
				{
					array = new int[this.magnitude.Length + 1];
					Array.Copy(this.magnitude, 0, array, 1, this.magnitude.Length);
					int_ = bigInteger_0.magnitude;
				}
				return new BigInteger(this.sign, this.method_0(array, int_));
			}
			return bigInteger_0;
		}
		public virtual int bitCount()
		{
			if (this.nBits == -1)
			{
				this.nBits = 0;
				for (int i = 0; i < this.magnitude.Length; i++)
				{
					this.nBits += (int)BigInteger.bitCounts[this.magnitude[i] & 255];
					this.nBits += (int)BigInteger.bitCounts[this.magnitude[i] >> 8 & 255];
					this.nBits += (int)BigInteger.bitCounts[this.magnitude[i] >> 16 & 255];
					this.nBits += (int)BigInteger.bitCounts[this.magnitude[i] >> 24 & 255];
				}
			}
			return this.nBits;
		}
		private int getBitLength(int indx, int[] int_0)
		{
			if (int_0.Length == 0)
			{
				return 0;
			}
			while (indx != int_0.Length && int_0[indx] == 0)
			{
				indx++;
			}
			if (indx == int_0.Length)
			{
				return 0;
			}
			int num = 32 * (int_0.Length - indx - 1);
			num += BigInteger.bitLen(int_0[indx]);
			if (this.sign < 0)
			{
				bool flag = BigInteger.bitCounts[int_0[indx] & 255] + BigInteger.bitCounts[int_0[indx] >> 8 & 255] + BigInteger.bitCounts[int_0[indx] >> 16 & 255] + BigInteger.bitCounts[int_0[indx] >> 24 & 255] == 1;
				int num2 = indx + 1;
				while (num2 < int_0.Length && flag)
				{
					flag = (int_0[num2] == 0);
					num2++;
				}
				num -= (flag ? 1 : 0);
			}
			return num;
		}
		public virtual int getBitLength()
		{
			if (this.nBitLength == -1)
			{
				if (this.sign == 0)
				{
					this.nBitLength = 0;
				}
				else
				{
					this.nBitLength = this.getBitLength(0, this.magnitude);
				}
			}
			return this.nBitLength;
		}
		internal static int bitLen(int int_0)
		{
			if (int_0 >= 32768)
			{
				if (int_0 >= 8388608)
				{
					if (int_0 >= 134217728)
					{
						if (int_0 >= 536870912)
						{
							if (int_0 >= 1073741824)
							{
								return 31;
							}
							return 30;
						}
						else
						{
							if (int_0 >= 268435456)
							{
								return 29;
							}
							return 28;
						}
					}
					else
					{
						if (int_0 >= 33554432)
						{
							if (int_0 >= 67108864)
							{
								return 27;
							}
							return 26;
						}
						else
						{
							if (int_0 >= 16777216)
							{
								return 25;
							}
							return 24;
						}
					}
				}
				else
				{
					if (int_0 >= 524288)
					{
						if (int_0 >= 2097152)
						{
							if (int_0 >= 4194304)
							{
								return 23;
							}
							return 22;
						}
						else
						{
							if (int_0 >= 1048576)
							{
								return 21;
							}
							return 20;
						}
					}
					else
					{
						if (int_0 >= 131072)
						{
							if (int_0 >= 262144)
							{
								return 19;
							}
							return 18;
						}
						else
						{
							if (int_0 >= 65536)
							{
								return 17;
							}
							return 16;
						}
					}
				}
			}
			else
			{
				if (int_0 >= 128)
				{
					if (int_0 >= 2048)
					{
						if (int_0 >= 8192)
						{
							if (int_0 >= 16384)
							{
								return 15;
							}
							return 14;
						}
						else
						{
							if (int_0 >= 4096)
							{
								return 13;
							}
							return 12;
						}
					}
					else
					{
						if (int_0 >= 512)
						{
							if (int_0 >= 1024)
							{
								return 11;
							}
							return 10;
						}
						else
						{
							if (int_0 >= 256)
							{
								return 9;
							}
							return 8;
						}
					}
				}
				else
				{
					if (int_0 >= 8)
					{
						if (int_0 >= 32)
						{
							if (int_0 >= 64)
							{
								return 7;
							}
							return 6;
						}
						else
						{
							if (int_0 >= 16)
							{
								return 5;
							}
							return 4;
						}
					}
					else
					{
						if (int_0 >= 2)
						{
							if (int_0 >= 4)
							{
								return 3;
							}
							return 2;
						}
						else
						{
							if (int_0 >= 1)
							{
								return 1;
							}
							if (int_0 >= 0)
							{
								return 0;
							}
							return 32;
						}
					}
				}
			}
		}
		public virtual int compareTo(object object_0)
		{
			return this.compareTo((BigInteger)object_0);
		}
		private int compareTo(int xIndx, int[] int_0, int yIndx, int[] int_1)
		{
			while (xIndx != int_0.Length && int_0[xIndx] == 0)
			{
				xIndx++;
			}
			while (yIndx != int_1.Length && int_1[yIndx] == 0)
			{
				yIndx++;
			}
			if (int_0.Length - xIndx < int_1.Length - yIndx)
			{
				return -1;
			}
			if (int_0.Length - xIndx > int_1.Length - yIndx)
			{
				return 1;
			}
			while (xIndx < int_0.Length)
			{
				long num = (long)int_0[xIndx++] & (long)((ulong)-1);
				long num2 = (long)int_1[yIndx++] & (long)((ulong)-1);
				if (num < num2)
				{
					return -1;
				}
				if (num > num2)
				{
					return 1;
				}
			}
			return 0;
		}
		public virtual int compareTo(BigInteger bigInteger_0)
		{
			if (this.sign < bigInteger_0.sign)
			{
				return -1;
			}
			if (this.sign > bigInteger_0.sign)
			{
				return 1;
			}
			return this.compareTo(0, this.magnitude, 0, bigInteger_0.magnitude);
		}
		private int[] divide(int[] int_0, int[] int_1)
		{
			int num = this.compareTo(0, int_0, 0, int_1);
			int[] array2;
			if (num > 0)
			{
				int num2 = this.getBitLength(0, int_0) - this.getBitLength(0, int_1);
				int[] array;
				if (num2 > 1)
				{
					array = this.shiftLeft(int_1, num2 - 1);
					array2 = this.shiftLeft(BigInteger.ONE.magnitude, num2 - 1);
					if (num2 % 32 == 0)
					{
						int[] array3 = new int[num2 / 32 + 1];
						Array.Copy(array2, 0, array3, 1, array3.Length - 1);
						array3[0] = 0;
						array2 = array3;
					}
				}
				else
				{
					array = new int[int_0.Length];
					array2 = new int[1];
					Array.Copy(int_1, 0, array, array.Length - int_1.Length, int_1.Length);
					array2[0] = 1;
				}
				int[] array4 = new int[array2.Length];
				this.subtract(0, int_0, 0, array);
				Array.Copy(array2, 0, array4, 0, array2.Length);
				int num3 = 0;
				int num4 = 0;
				int num5 = 0;
				while (true)
				{
					for (int i = this.compareTo(num3, int_0, num4, array); i >= 0; i = this.compareTo(num3, int_0, num4, array))
					{
						this.subtract(num3, int_0, num4, array);
						this.method_0(array2, array4);
					}
					num = this.compareTo(num3, int_0, 0, int_1);
					if (num <= 0)
					{
						break;
					}
					if (int_0[num3] == 0)
					{
						num3++;
					}
					num2 = this.getBitLength(num4, array) - this.getBitLength(num3, int_0);
					if (num2 == 0)
					{
						array = this.shiftRightOne(num4, array);
						array4 = this.shiftRightOne(num5, array4);
					}
					else
					{
						array = this.shiftRight(num4, array, num2);
						array4 = this.shiftRight(num5, array4, num2);
					}
					if (array[num4] == 0)
					{
						num4++;
					}
					if (array4[num5] == 0)
					{
						num5++;
					}
				}
				if (num == 0)
				{
					this.method_0(array2, BigInteger.ONE.magnitude);
					for (int num6 = num3; num6 != int_0.Length; num6++)
					{
						int_0[num6] = 0;
					}
				}
			}
			else
			{
				if (num == 0)
				{
					array2 = new int[]
					{
						1
					};
				}
				else
				{
					array2 = new int[]
					{
						0
					};
				}
			}
			return array2;
		}
		public virtual BigInteger divide(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign == 0)
			{
				throw new ArithmeticException("Divide by zero");
			}
			if (this.sign == 0)
			{
				return BigInteger.ZERO;
			}
			if (bigInteger_0.compareTo(BigInteger.ONE) == 0)
			{
				return this;
			}
			int[] array = new int[this.magnitude.Length];
			Array.Copy(this.magnitude, 0, array, 0, array.Length);
			return new BigInteger(this.sign * bigInteger_0.sign, this.divide(array, bigInteger_0.magnitude));
		}
		public virtual BigInteger[] divideAndRemainder(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign == 0)
			{
				throw new ArithmeticException("Divide by zero");
			}
			BigInteger[] array = new BigInteger[2];
			if (this.sign == 0)
			{
				array[0] = (array[1] = BigInteger.ZERO);
				return array;
			}
			if (bigInteger_0.compareTo(BigInteger.ONE) == 0)
			{
				array[0] = this;
				array[1] = BigInteger.ZERO;
				return array;
			}
			int[] array2 = new int[this.magnitude.Length];
			Array.Copy(this.magnitude, 0, array2, 0, array2.Length);
			int[] int_ = this.divide(array2, bigInteger_0.magnitude);
			array[0] = new BigInteger(this.sign * bigInteger_0.sign, int_);
			array[1] = new BigInteger(this.sign, array2);
			return array;
		}
		public override bool Equals(object value)
		{
			if (value == this)
			{
				return true;
			}
			if (!(value is BigInteger))
			{
				return false;
			}
			BigInteger bigInteger = (BigInteger)value;
			if (bigInteger.sign == this.sign)
			{
				if (bigInteger.magnitude.Length == this.magnitude.Length)
				{
					for (int i = 0; i < this.magnitude.Length; i++)
					{
						if (bigInteger.magnitude[i] != this.magnitude[i])
						{
							return false;
						}
					}
					return true;
				}
			}
			return false;
		}
		public virtual BigInteger vmethod_2(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign == 0)
			{
				return this.vmethod_0();
			}
			if (this.sign == 0)
			{
				return bigInteger_0.vmethod_0();
			}
			BigInteger bigInteger = this;
			BigInteger bigInteger2 = bigInteger_0;
			while (bigInteger2.sign != 0)
			{
				BigInteger bigInteger3 = bigInteger.vmethod_5(bigInteger2);
				bigInteger = bigInteger2;
				bigInteger2 = bigInteger3;
			}
			return bigInteger;
		}
		public override int GetHashCode()
		{
			return 0;
		}
		public virtual int intValue()
		{
			if (this.magnitude.Length == 0)
			{
				return 0;
			}
			if (this.sign < 0)
			{
				return -this.magnitude[this.magnitude.Length - 1];
			}
			return this.magnitude[this.magnitude.Length - 1];
		}
		public virtual bool isProbablePrime(int certainty)
		{
			if (certainty == 0)
			{
				return true;
			}
			BigInteger bigInteger = this.vmethod_0();
			if (bigInteger.Equals(BigInteger.TWO))
			{
				return true;
			}
			if (!bigInteger.Equals(BigInteger.ONE) && bigInteger.testBit(0))
			{
				if ((certainty & 1) == 1)
				{
					certainty = certainty / 2 + 1;
				}
				else
				{
					certainty /= 2;
				}
				BigInteger bigInteger2 = bigInteger.subtract(BigInteger.ONE);
				int lowestSetBit = bigInteger2.LowestSetBit;
				bigInteger2 = bigInteger2.shiftRight(lowestSetBit);
				Random random_ = new Random();
				for (int i = 0; i <= certainty; i++)
				{
					BigInteger bigInteger3;
					do
					{
						bigInteger3 = new BigInteger(bigInteger.getBitLength(), random_);
					}
					while (bigInteger3.compareTo(BigInteger.ONE) <= 0 || bigInteger3.compareTo(bigInteger) >= 0);
					int num = 0;
					BigInteger bigInteger4 = bigInteger3.modPow(bigInteger2, bigInteger);
					while (true)
					{
						if (num == 0)
						{
							if (bigInteger4.Equals(BigInteger.ONE))
							{
								break;
							}
						}
						if (bigInteger4.Equals(bigInteger.subtract(BigInteger.ONE)))
						{
							break;
						}
						if (num > 0 && bigInteger4.Equals(BigInteger.ONE))
						{
							return false;
						}
						if (++num == lowestSetBit)
						{
							return false;
						}
						bigInteger4 = bigInteger4.modPow(BigInteger.TWO, bigInteger);
					}
				}
				return true;
			}
			return false;
		}
		public virtual long longValue()
		{
			if (this.magnitude.Length == 0)
			{
				return 0L;
			}
			long num;
			if (this.magnitude.Length > 1)
			{
				num = ((long)this.magnitude[this.magnitude.Length - 2] << 32 | ((long)this.magnitude[this.magnitude.Length - 1] & (long)((ulong)-1)));
			}
			else
			{
				num = ((long)this.magnitude[this.magnitude.Length - 1] & (long)((ulong)-1));
			}
			if (this.sign < 0)
			{
				return -num;
			}
			return num;
		}
		public virtual BigInteger vmethod_3(BigInteger bigInteger_0)
		{
			if (this.compareTo(bigInteger_0) <= 0)
			{
				return bigInteger_0;
			}
			return this;
		}
		public virtual BigInteger vmethod_4(BigInteger bigInteger_0)
		{
			if (this.compareTo(bigInteger_0) >= 0)
			{
				return bigInteger_0;
			}
			return this;
		}
		public virtual BigInteger vmethod_5(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign <= 0)
			{
				throw new ArithmeticException("BigInteger: modulus is not positive");
			}
			BigInteger bigInteger = this.remainder(bigInteger_0);
			if (bigInteger.sign < 0)
			{
				return bigInteger.vmethod_1(bigInteger_0);
			}
			return bigInteger;
		}
		public virtual BigInteger modInverse(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign != 1)
			{
				throw new ArithmeticException("Modulus must be positive");
			}
			BigInteger bigInteger = new BigInteger();
			BigInteger u2Out = new BigInteger();
			BigInteger bigInteger2 = BigInteger.extEuclid(this, bigInteger_0, bigInteger, u2Out);
			if (!bigInteger2.Equals(BigInteger.ONE))
			{
				throw new ArithmeticException("Numbers not relatively prime.");
			}
			if (bigInteger.compareTo(BigInteger.ZERO) < 0)
			{
				bigInteger = bigInteger.vmethod_1(bigInteger_0);
			}
			return bigInteger;
		}
		private static BigInteger extEuclid(BigInteger bigInteger_0, BigInteger bigInteger_1, BigInteger u1Out, BigInteger u2Out)
		{
			BigInteger bigInteger = BigInteger.ONE;
			BigInteger bigInteger2 = bigInteger_0;
			BigInteger bigInteger3 = BigInteger.ZERO;
			BigInteger bigInteger4 = bigInteger_1;
			while (bigInteger4.compareTo(BigInteger.ZERO) > 0)
			{
				BigInteger bigInteger_2 = bigInteger2.divide(bigInteger4);
				BigInteger bigInteger5 = bigInteger.subtract(bigInteger3.multiply(bigInteger_2));
				bigInteger = bigInteger3;
				bigInteger3 = bigInteger5;
				bigInteger5 = bigInteger2.subtract(bigInteger4.multiply(bigInteger_2));
				bigInteger2 = bigInteger4;
				bigInteger4 = bigInteger5;
			}
			u1Out.sign = bigInteger.sign;
			u1Out.magnitude = bigInteger.magnitude;
			BigInteger bigInteger6 = bigInteger2.subtract(bigInteger.multiply(bigInteger_0)).divide(bigInteger_1);
			u2Out.sign = bigInteger6.sign;
			u2Out.magnitude = bigInteger6.magnitude;
			return bigInteger2;
		}
		private void zero(int[] int_0)
		{
			for (int num = 0; num != int_0.Length; num++)
			{
				int_0[num] = 0;
			}
		}
		public virtual BigInteger modPow(BigInteger exponent, BigInteger bigInteger_0)
		{
			int[] array = null;
			int[] array2 = null;
			bool flag = (bigInteger_0.magnitude[bigInteger_0.magnitude.Length - 1] & 1) == 1;
			long num = 0L;
			if (flag)
			{
				num = bigInteger_0.MQuote;
				BigInteger bigInteger = this.shiftLeft(32 * bigInteger_0.magnitude.Length).vmethod_5(bigInteger_0);
				array = bigInteger.magnitude;
				if (flag = (array.Length <= bigInteger_0.magnitude.Length))
				{
					array2 = new int[bigInteger_0.magnitude.Length + 1];
					if (array.Length < bigInteger_0.magnitude.Length)
					{
						int[] array3 = new int[bigInteger_0.magnitude.Length];
						Array.Copy(array, 0, array3, array3.Length - array.Length, array.Length);
						array = array3;
					}
				}
			}
			if (!flag)
			{
				if (this.magnitude.Length <= bigInteger_0.magnitude.Length)
				{
					array = new int[bigInteger_0.magnitude.Length];
					Array.Copy(this.magnitude, 0, array, array.Length - this.magnitude.Length, this.magnitude.Length);
				}
				else
				{
					BigInteger bigInteger2 = this.remainder(bigInteger_0);
					array = new int[bigInteger_0.magnitude.Length];
					Array.Copy(bigInteger2.magnitude, 0, array, array.Length - bigInteger2.magnitude.Length, bigInteger2.magnitude.Length);
				}
				array2 = new int[bigInteger_0.magnitude.Length * 2];
			}
			int[] array4 = new int[bigInteger_0.magnitude.Length];
			for (int i = 0; i < exponent.magnitude.Length; i++)
			{
				int j = exponent.magnitude[i];
				int k = 0;
				if (i == 0)
				{
					while (j > 0)
					{
						j <<= 1;
						k++;
					}
					Array.Copy(array, 0, array4, 0, array.Length);
					j <<= 1;
					k++;
				}
				while (j != 0)
				{
					if (flag)
					{
						this.multiplyMonty(array2, array4, array4, bigInteger_0.magnitude, num);
					}
					else
					{
						this.square(array2, array4);
						this.remainder(array2, bigInteger_0.magnitude);
						Array.Copy(array2, array2.Length - array4.Length, array4, 0, array4.Length);
						this.zero(array2);
					}
					k++;
					if (j < 0)
					{
						if (flag)
						{
							this.multiplyMonty(array2, array4, array, bigInteger_0.magnitude, num);
						}
						else
						{
							this.multiply(array2, array4, array);
							this.remainder(array2, bigInteger_0.magnitude);
							Array.Copy(array2, array2.Length - array4.Length, array4, 0, array4.Length);
							this.zero(array2);
						}
					}
					j <<= 1;
				}
				while (k < 32)
				{
					if (flag)
					{
						this.multiplyMonty(array2, array4, array4, bigInteger_0.magnitude, num);
					}
					else
					{
						this.square(array2, array4);
						this.remainder(array2, bigInteger_0.magnitude);
						Array.Copy(array2, array2.Length - array4.Length, array4, 0, array4.Length);
						this.zero(array2);
					}
					k++;
				}
			}
			if (flag)
			{
				this.zero(array);
				array[array.Length - 1] = 1;
				this.multiplyMonty(array2, array4, array, bigInteger_0.magnitude, num);
			}
			return new BigInteger(1, array4);
		}
		private int[] square(int[] int_0, int[] int_1)
		{
			if (int_0.Length != 2 * int_1.Length)
			{
				throw new ArgumentException("no I don't think so...");
			}
			long num3;
			long num4;
			for (int num = int_1.Length - 1; num != 0; num--)
			{
				long num2 = (long)int_1[num] & (long)((ulong)-1);
				num3 = num2 * num2;
				num4 = SupportClass.URShift(num3, 32);
				num3 &= (long)((ulong)-1);
				num3 += ((long)int_0[2 * num + 1] & (long)((ulong)-1));
				int_0[2 * num + 1] = (int)num3;
				long num5 = num4 + (num3 >> 32);
				for (int i = num - 1; i >= 0; i--)
				{
					num3 = ((long)int_1[i] & (long)((ulong)-1)) * num2;
					num4 = SupportClass.URShift(num3, 31);
					num3 = (num3 & 2147483647L) << 1;
					num3 += ((long)int_0[num + i + 1] & (long)((ulong)-1)) + num5;
					int_0[num + i + 1] = (int)num3;
					num5 = num4 + SupportClass.URShift(num3, 32);
				}
				num5 += ((long)int_0[num] & (long)((ulong)-1));
				int_0[num] = (int)num5;
				int_0[num - 1] = (int)(num5 >> 32);
			}
			num3 = ((long)int_1[0] & (long)((ulong)-1));
			num3 *= num3;
			num4 = SupportClass.URShift(num3, 32);
			num3 &= (long)((ulong)-1);
			num3 += ((long)int_0[1] & (long)((ulong)-1));
			int_0[1] = (int)num3;
			int_0[0] = (int)(num4 + (num3 >> 32) + (long)int_0[0]);
			return int_0;
		}
		private int[] multiply(int[] int_0, int[] int_1, int[] int_2)
		{
			for (int i = int_2.Length - 1; i >= 0; i--)
			{
				long num = (long)int_2[i] & (long)((ulong)-1);
				long num2 = 0L;
				for (int j = int_1.Length - 1; j >= 0; j--)
				{
					num2 += num * ((long)int_1[j] & (long)((ulong)-1)) + ((long)int_0[i + j + 1] & (long)((ulong)-1));
					int_0[i + j + 1] = (int)num2;
					num2 = SupportClass.URShift(num2, 32);
				}
				int_0[i] = (int)num2;
			}
			return int_0;
		}
		private long _extEuclid(long long_0, long long_1, long[] uOut)
		{
			long num = 1L;
			long num2 = long_0;
			long num3 = 0L;
			long num6;
			for (long num4 = long_1; num4 > 0L; num4 = num6)
			{
				long num5 = num2 / num4;
				num6 = num - num3 * num5;
				num = num3;
				num3 = num6;
				num6 = num2 - num4 * num5;
				num2 = num4;
			}
			uOut[0] = num;
			long num7 = (num2 - num * long_0) / long_1;
			uOut[1] = num7;
			return num2;
		}
		private long _modInverse(long long_0, long long_1)
		{
			if (long_1 < 0L)
			{
				throw new ArithmeticException("Modulus must be positive");
			}
			long[] array = new long[2];
			long num = this._extEuclid(long_0, long_1, array);
			if (num != 1L)
			{
				throw new ArithmeticException("Numbers not relatively prime.");
			}
			if (array[0] < 0L)
			{
				array[0] = array[0] + long_1;
			}
			return array[0];
		}
		public virtual void multiplyMonty(int[] int_0, int[] int_1, int[] int_2, int[] int_3, long mQuote)
		{
			int num = int_3.Length;
			int num2 = num - 1;
			long num3 = (long)int_2[num - 1] & (long)((ulong)-1);
			for (int i = 0; i <= num; i++)
			{
				int_0[i] = 0;
			}
			for (int j = num; j > 0; j--)
			{
				long num4 = (long)int_1[j - 1] & (long)((ulong)-1);
				long num5 = (((long)int_0[num] & (long)((ulong)-1)) + (num4 * num3 & (long)((ulong)-1)) & (long)((ulong)-1)) * mQuote & (long)((ulong)-1);
				long num6 = num4 * num3;
				long num7 = num5 * ((long)int_3[num - 1] & (long)((ulong)-1));
				long num8 = ((long)int_0[num] & (long)((ulong)-1)) + (num6 & (long)((ulong)-1)) + (num7 & (long)((ulong)-1));
				long num9 = SupportClass.URShift(num6, 32) + SupportClass.URShift(num7, 32) + SupportClass.URShift(num8, 32);
				for (int k = num2; k > 0; k--)
				{
					num6 = num4 * ((long)int_2[k - 1] & (long)((ulong)-1));
					num7 = num5 * ((long)int_3[k - 1] & (long)((ulong)-1));
					num8 = ((long)int_0[k] & (long)((ulong)-1)) + (num6 & (long)((ulong)-1)) + (num7 & (long)((ulong)-1)) + (num9 & (long)((ulong)-1));
					num9 = SupportClass.URShift(num9, 32) + SupportClass.URShift(num6, 32) + SupportClass.URShift(num7, 32) + SupportClass.URShift(num8, 32);
					int_0[k + 1] = (int)num8;
				}
				num9 += ((long)int_0[0] & (long)((ulong)-1));
				int_0[1] = (int)num9;
				int_0[0] = (int)SupportClass.URShift(num9, 32);
			}
			if (this.compareTo(0, int_0, 0, int_3) >= 0)
			{
				this.subtract(0, int_0, 0, int_3);
			}
			for (int l = 0; l < num; l++)
			{
				int_1[l] = int_0[l + 1];
			}
		}
		public virtual BigInteger multiply(BigInteger bigInteger_0)
		{
			if (this.sign != 0 && bigInteger_0.sign != 0)
			{
				int[] int_ = new int[this.magnitude.Length + bigInteger_0.magnitude.Length];
				return new BigInteger(this.sign * bigInteger_0.sign, this.multiply(int_, this.magnitude, bigInteger_0.magnitude));
			}
			return BigInteger.ZERO;
		}
		public virtual BigInteger negate()
		{
			return new BigInteger(-this.sign, this.magnitude);
		}
		public virtual BigInteger vmethod_6(int int_0)
		{
			if (int_0 < 0)
			{
				throw new ArithmeticException("Negative exponent");
			}
			if (this.sign != 0)
			{
				BigInteger bigInteger = BigInteger.ONE;
				BigInteger bigInteger2 = this;
				while (int_0 != 0)
				{
					if ((int_0 & 1) == 1)
					{
						bigInteger = bigInteger.multiply(bigInteger2);
					}
					int_0 >>= 1;
					if (int_0 != 0)
					{
						bigInteger2 = bigInteger2.multiply(bigInteger2);
					}
				}
				return bigInteger;
			}
			if (int_0 != 0)
			{
				return this;
			}
			return BigInteger.ONE;
		}
		private int[] remainder(int[] int_0, int[] int_1)
		{
			int num = this.compareTo(0, int_0, 0, int_1);
			if (num > 0)
			{
				int num2 = this.getBitLength(0, int_0) - this.getBitLength(0, int_1);
				int[] array;
				if (num2 > 1)
				{
					array = this.shiftLeft(int_1, num2 - 1);
				}
				else
				{
					array = new int[int_0.Length];
					Array.Copy(int_1, 0, array, array.Length - int_1.Length, int_1.Length);
				}
				this.subtract(0, int_0, 0, array);
				int num3 = 0;
				int num4 = 0;
				while (true)
				{
					for (int i = this.compareTo(num3, int_0, num4, array); i >= 0; i = this.compareTo(num3, int_0, num4, array))
					{
						this.subtract(num3, int_0, num4, array);
					}
					num = this.compareTo(num3, int_0, 0, int_1);
					if (num <= 0)
					{
						break;
					}
					if (int_0[num3] == 0)
					{
						num3++;
					}
					num2 = this.getBitLength(num4, array) - this.getBitLength(num3, int_0);
					if (num2 == 0)
					{
						array = this.shiftRightOne(num4, array);
					}
					else
					{
						array = this.shiftRight(num4, array, num2);
					}
					if (array[num4] == 0)
					{
						num4++;
					}
				}
				if (num == 0)
				{
					for (int num5 = num3; num5 != int_0.Length; num5++)
					{
						int_0[num5] = 0;
					}
				}
			}
			else
			{
				if (num == 0)
				{
					for (int num6 = 0; num6 != int_0.Length; num6++)
					{
						int_0[num6] = 0;
					}
				}
			}
			return int_0;
		}
		public virtual BigInteger remainder(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign == 0)
			{
				throw new ArithmeticException("BigInteger: Divide by zero");
			}
			if (this.sign == 0)
			{
				return BigInteger.ZERO;
			}
			int[] array = new int[this.magnitude.Length];
			Array.Copy(this.magnitude, 0, array, 0, array.Length);
			return new BigInteger(this.sign, this.remainder(array, bigInteger_0.magnitude));
		}
		private int[] shiftLeft(int[] int_0, int int_1)
		{
			int num = SupportClass.URShift(int_1, 5);
			int num2 = int_1 & 31;
			int num3 = int_0.Length;
			int[] array;
			if (num2 == 0)
			{
				array = new int[num3 + num];
				for (int i = 0; i < num3; i++)
				{
					array[i] = int_0[i];
				}
			}
			else
			{
				int num4 = 0;
				int bits = 32 - num2;
				int num5 = SupportClass.URShift(int_0[0], bits);
				if (num5 != 0)
				{
					array = new int[num3 + num + 1];
					array[num4++] = num5;
				}
				else
				{
					array = new int[num3 + num];
				}
				int num6 = int_0[0];
				for (int j = 0; j < num3 - 1; j++)
				{
					int num7 = int_0[j + 1];
					array[num4++] = (num6 << num2 | SupportClass.URShift(num7, bits));
					num6 = num7;
				}
				array[num4] = int_0[num3 - 1] << num2;
			}
			return array;
		}
		public virtual BigInteger shiftLeft(int int_0)
		{
			if (this.sign == 0 || this.magnitude.Length == 0)
			{
				return BigInteger.ZERO;
			}
			if (int_0 == 0)
			{
				return this;
			}
			if (int_0 < 0)
			{
				return this.shiftRight(-int_0);
			}
			return new BigInteger(this.sign, this.shiftLeft(this.magnitude, int_0));
		}
		private int[] shiftRight(int start, int[] int_0, int int_1)
		{
			int num = SupportClass.URShift(int_1, 5) + start;
			int num2 = int_1 & 31;
			int num3 = int_0.Length;
			if (num != start)
			{
				int num4 = num - start;
				for (int i = num3 - 1; i >= num; i--)
				{
					int_0[i] = int_0[i - num4];
				}
				for (int j = num - 1; j >= start; j--)
				{
					int_0[j] = 0;
				}
			}
			if (num2 != 0)
			{
				int num5 = 32 - num2;
				int number = int_0[num3 - 1];
				for (int k = num3 - 1; k >= num + 1; k--)
				{
					int num6 = int_0[k - 1];
					int_0[k] = (SupportClass.URShift(number, num2) | num6 << num5);
					number = num6;
				}
				int_0[num] = SupportClass.URShift(int_0[num], num2);
			}
			return int_0;
		}
		private int[] shiftRightOne(int start, int[] int_0)
		{
			int num = int_0.Length;
			int number = int_0[num - 1];
			for (int i = num - 1; i >= start + 1; i--)
			{
				int num2 = int_0[i - 1];
				int_0[i] = (SupportClass.URShift(number, 1) | num2 << 31);
				number = num2;
			}
			int_0[start] = SupportClass.URShift(int_0[start], 1);
			return int_0;
		}
		public virtual BigInteger shiftRight(int int_0)
		{
			if (int_0 == 0)
			{
				return this;
			}
			if (int_0 < 0)
			{
				return this.shiftLeft(-int_0);
			}
			if (int_0 < this.getBitLength())
			{
				int[] array = new int[this.magnitude.Length];
				Array.Copy(this.magnitude, 0, array, 0, array.Length);
				return new BigInteger(this.sign, this.shiftRight(0, array, int_0));
			}
			if (this.sign >= 0)
			{
				return BigInteger.ZERO;
			}
			return BigInteger.valueOf(-1L);
		}
		public virtual int signum()
		{
			return this.sign;
		}
		private int[] subtract(int xStart, int[] int_0, int yStart, int[] int_1)
		{
			int i = int_0.Length - 1;
			int num = int_1.Length - 1;
			int num2 = 0;
			do
			{
				long num3 = ((long)int_0[i] & (long)((ulong)-1)) - ((long)int_1[num--] & (long)((ulong)-1)) + (long)num2;
				int_0[i--] = (int)num3;
				if (num3 < 0L)
				{
					num2 = -1;
				}
				else
				{
					num2 = 0;
				}
			}
			while (num >= yStart);
			while (i >= xStart)
			{
				long num3 = ((long)int_0[i] & (long)((ulong)-1)) + (long)num2;
				int_0[i--] = (int)num3;
				if (num3 >= 0L)
				{
					break;
				}
				num2 = -1;
			}
			return int_0;
		}
		public virtual BigInteger subtract(BigInteger bigInteger_0)
		{
			if (bigInteger_0.sign == 0 || bigInteger_0.magnitude.Length == 0)
			{
				return this;
			}
			if (this.sign == 0 || this.magnitude.Length == 0)
			{
				return bigInteger_0.negate();
			}
			if (bigInteger_0.sign < 0)
			{
				if (this.sign > 0)
				{
					return this.vmethod_1(bigInteger_0.negate());
				}
			}
			else
			{
				if (this.sign < 0)
				{
					return this.vmethod_1(bigInteger_0.negate());
				}
			}
			int num = this.compareTo(bigInteger_0);
			if (num == 0)
			{
				return BigInteger.ZERO;
			}
			BigInteger bigInteger;
			BigInteger bigInteger2;
			if (num < 0)
			{
				bigInteger = bigInteger_0;
				bigInteger2 = this;
			}
			else
			{
				bigInteger = this;
				bigInteger2 = bigInteger_0;
			}
			int[] array = new int[bigInteger.magnitude.Length];
			Array.Copy(bigInteger.magnitude, 0, array, 0, array.Length);
			return new BigInteger(this.sign * num, this.subtract(0, array, 0, bigInteger2.magnitude));
		}
		public virtual byte[] toByteArray()
		{
			int bitLength = this.getBitLength();
			byte[] array = new byte[bitLength / 8 + 1];
			int num = 4;
			int num2 = 0;
			int num3 = this.magnitude.Length - 1;
			int num4 = 1;
			for (int i = array.Length - 1; i >= 0; i--)
			{
				if (num == 4 && num3 >= 0)
				{
					if (this.sign < 0)
					{
						long num5 = (long)(~(long)this.magnitude[num3--]) & (long)((ulong)-1);
						num5 += (long)num4;
						if ((num5 & -4294967296L) != 0L)
						{
							num4 = 1;
						}
						else
						{
							num4 = 0;
						}
						num2 = (int)(num5 & (long)((ulong)-1));
					}
					else
					{
						num2 = this.magnitude[num3--];
					}
					num = 1;
				}
				else
				{
					num2 = SupportClass.URShift(num2, 8);
					num++;
				}
				array[i] = (byte)num2;
			}
			return array;
		}
		public override string ToString()
		{
			return this.toString(10);
		}
		public virtual string toString(int int_0)
		{
			if (this.magnitude == null)
			{
				return "null";
			}
			if (this.sign == 0)
			{
				return "0";
			}
			string text = new StringBuilder().ToString();
			if (int_0 == 16)
			{
				for (int i = 0; i < this.magnitude.Length; i++)
				{
					string text2 = "0000000" + Convert.ToString(this.magnitude[i], 16);
					text2 = text2.Substring(text2.get_Length() - 8);
					text += text2;
				}
			}
			else
			{
				List<object> list = new List<object>();
				BigInteger bigInteger_ = new BigInteger(Convert.ToString(int_0, int_0), int_0);
				BigInteger bigInteger = new BigInteger(this.vmethod_0().toString(16), 16);
				while (!bigInteger.Equals(BigInteger.ZERO))
				{
					BigInteger bigInteger2 = bigInteger.vmethod_5(bigInteger_);
					if (bigInteger2.Equals(BigInteger.ZERO))
					{
						list.Add("0");
					}
					else
					{
						list.Add(Convert.ToString(bigInteger2.magnitude[0], int_0));
					}
					bigInteger = bigInteger.divide(bigInteger_);
				}
				while (list.get_Count() != 0)
				{
					text += SupportClass.StackSupport.Pop(list);
				}
			}
			while (text.get_Length() > 1)
			{
				if (text.get_Chars(0) != '0')
				{
					break;
				}
				text = text.Substring(1);
			}
			if (text.get_Length() == 0)
			{
				text = "0";
			}
			else
			{
				if (this.sign == -1)
				{
					text = "-" + text;
				}
			}
			return text;
		}
		public static BigInteger valueOf(long long_0)
		{
			if (long_0 == 0L)
			{
				return BigInteger.ZERO;
			}
			byte[] array = new byte[8];
			for (int i = 0; i < 8; i++)
			{
				array[7 - i] = (byte)long_0;
				long_0 >>= 8;
			}
			return new BigInteger(array);
		}
		private int method_2(int int_0, int int_1)
		{
			if (int_0 < int_1)
			{
				return int_1;
			}
			return int_0;
		}
		public virtual bool testBit(int int_0)
		{
			if (int_0 < 0)
			{
				throw new ArithmeticException("Bit position must not be negative");
			}
			if (int_0 / 32 >= this.magnitude.Length)
			{
				return this.sign < 0;
			}
			return (this.magnitude[this.magnitude.Length - 1 - int_0 / 32] >> int_0 % 32 & 1) > 0;
		}
		static BigInteger()
		{
			// Note: this type is marked as 'beforefieldinit'.
			byte[] array = new byte[]
			{
				0,
				127,
				63,
				31,
				15,
				7,
				3,
				1
			};
			array[0] = (byte)SupportClass.Identity(255L);
			BigInteger.rndMask = array;
			BigInteger.bitCounts = new byte[]
			{
				0,
				1,
				1,
				2,
				1,
				2,
				2,
				3,
				1,
				2,
				2,
				3,
				2,
				3,
				3,
				4,
				1,
				2,
				2,
				3,
				2,
				3,
				3,
				4,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				1,
				2,
				2,
				3,
				2,
				3,
				3,
				4,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				1,
				2,
				2,
				3,
				2,
				3,
				3,
				4,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				4,
				5,
				5,
				6,
				5,
				6,
				6,
				7,
				1,
				2,
				2,
				3,
				2,
				3,
				3,
				4,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				4,
				5,
				5,
				6,
				5,
				6,
				6,
				7,
				2,
				3,
				3,
				4,
				3,
				4,
				4,
				5,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				4,
				5,
				5,
				6,
				5,
				6,
				6,
				7,
				3,
				4,
				4,
				5,
				4,
				5,
				5,
				6,
				4,
				5,
				5,
				6,
				5,
				6,
				6,
				7,
				4,
				5,
				5,
				6,
				5,
				6,
				6,
				7,
				5,
				6,
				6,
				7,
				6,
				7,
				7,
				8
			};
			BigInteger.bitLengths = new byte[]
			{
				0,
				1,
				2,
				2,
				3,
				3,
				3,
				3,
				4,
				4,
				4,
				4,
				4,
				4,
				4,
				4,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				5,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				6,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				7,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8,
				8
			};
			BigInteger.ZERO = new BigInteger(0, new byte[0]);
			BigInteger.ONE = BigInteger.valueOf(1L);
			BigInteger.TWO = BigInteger.valueOf(2L);
		}
	}
}
